package cn.chen.数据结构.队列;

/**
 * 利用数组模拟环形队列
 * */
public class ArrayQueue {

    private int maxSize;    // 队列的长度
    private int head,tail;  // 队列的头尾指针
    private int count;  // 队列中元素的个数，默认值为0
    private int[] queue;    // 队列

    // 创建队列
    public ArrayQueue(int maxSize) {

        this.maxSize=maxSize;
        queue=new int[this.maxSize];

        // 头尾现在都是-1
        head=-1;
        tail=-1;
    }
    // 往队列添加元素
    public void addElem(int elem){

        // (head++)%maxSize 的值 会在数组索引从0开始都maxSize一直循环
        if(isFull()){  // 队列未满

            throw new RuntimeException("队列已满，不能添加");
        }
        else {

            queue[(++tail)%maxSize]=elem;
            count++;    // 计数加1
        }
    }
    // 显示队头元素，但是不删除
    public int getElem(){

        if(isEmpty()){   // 队列不为空

            throw new RuntimeException("队列为空，不能取出");
        }
        else {
            return queue[(head+1) % maxSize];   // head+1：因为这里只是获取队头元素，并没有删除，所以这里只需要head+1获取到元素就可以，head指针是不需要改变的
        }
    }
    // 从队列取出元素并且删除元素
    public int removeElem(){

        if(isEmpty()){   // 队列不为空

            throw new RuntimeException("队列为空，不能取出");
        }
        else {
            int i = (++head) % maxSize;
            int remove=queue[i];
            queue[i]=0; // 该元素已经被取出了，所以应该赋值为0
            count--;    // 计数减1
            return remove;
        }
    }
    // 显示队列所有元素,从对头到队尾遍历
    public void print(){

        if(isEmpty()) {
            System.out.println("队列为空，没有数据");
            return; // 不会往后面运行了
        }
        for(int i=head+1,j=0;j<count;j++){

            System.out.printf("%d\t",queue[(i++)%maxSize]);
        }
    }
    // 判断队列是否已经满了
    public boolean isFull(){

        if(count==maxSize)
            return true;    // 队满，返回true
        else return false;
    }
    // 判断队列是否为空
    public boolean isEmpty(){

        if(count==0)
            return true;    // 队列为空，返回true
        else return false;
    }
}
